package com.guigu.work.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.base.entity.CoreOrg;
import com.guigu.base.entity.GlobalUser;
import com.guigu.base.entity.dto.*;
import com.guigu.base.entity.vo.TransportLineVO;
import com.guigu.base.entity.vo.TransportOrderDashboardVO;
import com.guigu.dispatch.entity.CacheLineUse;
import com.guigu.dispatch.entity.OrderClassify;
import com.guigu.dispatch.entity.OrderClassifyAttach;
import com.guigu.dispatch.entity.OrderClassifyOrder;
import com.guigu.order.entity.Order;
import com.guigu.tms.exception.TmsException;
import com.guigu.tms.result.R;
import com.guigu.tms.result.ResultCode;
import com.guigu.work.dto.TransportOrderDTO;
import com.guigu.work.entity.TransportOrder;
import com.guigu.work.feign.BaseFeign;
import com.guigu.work.feign.DispatchFeign;
import com.guigu.work.feign.OrderFeign;
import com.guigu.work.mapper.TransportOrderMapper;
import com.guigu.work.service.TransportOrderService;
import com.guigu.work.vo.TransportOrderDetailsVO;
import com.guigu.work.vo.TransportOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 运单表 服务实现类
 * </p>
 *
 * @author liAo
 * @since 2021-11-09
 */
@Slf4j
@Service
@Transactional
public class TransportOrderServiceImpl extends ServiceImpl<TransportOrderMapper, TransportOrder> implements TransportOrderService {

    @Autowired(required = false)
    private TransportOrderMapper mapper;

    @Autowired
    private BaseFeign baseFeign;

    @Autowired
    private DispatchFeign dispatchFeign;

    @Autowired
    private OrderFeign orderFeign;

    /**
     * 新增运单
     *
     * @param dto 运单信息
     * @return 运单信息
     */
    @Override
    public TransportOrder saveTransportOrder(TransportOrderDTO dto) {
        if (null == dto) {
            throw new IllegalArgumentException("参数异常!");
        }
        // scheduling_status 1.待调度2.未匹配线路3.已调度
        dto.setSchedulingStatus(1);
        //status 1.新建 2.已装车 3.到达 4.到达终端网点 5.已签收
        dto.setStatus(1);
        //create_time
        dto.setCreateTime(new Date());
        //添加
        this.saveOrUpdate(dto);
        log.info("运单数据为:{}", dto);
        return dto;
    }

    /**
     * 修改运单信息
     *
     * @param dto
     * @return
     */
    @Override
    public TransportOrder updateTransportOrder(TransportOrderDTO dto) {
        if (null == dto) {
            throw new IllegalArgumentException("参数异常!");
        }
        this.saveOrUpdate(dto);
        return dto;
    }

    /**
     * 分页条件查询
     * 页码-页尺寸-订单Id-运单状态-运单调度状态
     *
     * @param dto
     * @return
     */
    @Override
    public IPage<TransportOrder> findByPage(TransportOrderDTO dto) {
        if (null == dto) {
            throw new IllegalArgumentException("参数异常!");
        }
        Page<TransportOrder> page = new Page<TransportOrder>(dto.getPage(), dto.getPageSize());

        LambdaQueryWrapper<TransportOrder> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getOrderId())) {
            wrapper.eq(TransportOrder::getOrderId, dto.getOrderId());
        }
        if (null != dto.getStatus() || dto.getStatus() > 0) {
            wrapper.eq(TransportOrder::getStatus, dto.getStatus());
        }

        if (null != dto.getSchedulingStatus() || dto.getSchedulingStatus() > 0) {
            wrapper.eq(TransportOrder::getSchedulingStatus, dto.getSchedulingStatus());
        }


        IPage<TransportOrder> orderIPage = this.page(page, wrapper);
        return orderIPage;
    }

    /**
     * 根据订单id获取运单信息
     *
     * @param orderId
     * @return
     */
    @Override
    public TransportOrder findByOrderId(String orderId) {
        if (StringUtils.isNotBlank(orderId)) {
            throw new IllegalArgumentException("参数异常!");
        }

        return this.getOne(new LambdaQueryWrapper<TransportOrder>().eq(
                TransportOrder::getOrderId, orderId));
    }

    /**
     * 根据多条件查询运单信息
     *
     * @param dto
     * @return TransportOrder
     */
    @Override
    public List<TransportOrder> findByOrderIds(TransportOrderDTO dto) {
        if (null == dto) {
            throw new IllegalArgumentException("参数异常!");
        }
        LambdaQueryWrapper<TransportOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(TransportOrder::getOrderId, dto.getOrderIds());
        if (null != dto.getStatus() || dto.getStatus() > 0) {
            wrapper.eq(TransportOrder::getStatus, dto.getStatus());
        }
        if (null != dto.getSchedulingStatus() || dto.getSchedulingStatus() > 0) {
            wrapper.eq(TransportOrder::getSchedulingStatus, dto.getSchedulingStatus());
        }

        return this.list(wrapper);
    }


    /**
     * 根据运单Id查询运单详情
     *
     * @param transportOrderId
     * @return
     */
    @Override
    public R<TransportOrderDTO> findTransportOrderDetailsById(String transportOrderId) {
        TransportOrderDTO transportOrderDTO = new TransportOrderDTO();
        /**
         * 1.查询运单本身信息
         */
        TransportOrder transportOrder = this.baseMapper.selectById(transportOrderId);
        /**
         * 开始转换
         */
        BeanUtil.copyProperties(transportOrder, transportOrderDTO);
        if (ObjectUtils.isEmpty(transportOrderDTO)) {
            throw new TmsException(ResultCode.ERROR_CODE, "您要查询的值为null");
        }
        /**
         * 2.获取线路信息
         * 根据订单Id查找订单分类,在根据订单分类查找下线路和订单分类的中间表,在根据线路Id查找线路
         */
        getLineInformation(transportOrderDTO);

        /**
         * 3.获取车次车辆司机数据
         */
        getTheVehicleDriver(transportOrderDTO);

        /**
         * 4.查询其订单信息
         */
        Order order = orderFeign.getOrderById(transportOrderDTO.getOrderId());
        if (ObjectUtils.isNotEmpty(order)) {
            transportOrderDTO.setOrder(order);
        }

        return new R<>(ResultCode.SUCCESS_CODE, transportOrderDTO);
    }


    /**
     * 根据订单ID查询其对应的线路,车次,车辆,司机数据
     *
     * @param orderId 订单Id
     * @return
     */
    @Override
    public R<TransportOrderDetailsVO> findTransportOrderDetailsByOrderById(String orderId) {
        TransportOrderDetailsVO transportOrderDetailsVO = new TransportOrderDetailsVO();
        /**
         * 获取订单分类和订单的中间表数据
         */
        List<OrderClassifyOrder> list = dispatchFeign.findByOrderId(orderId).getData();
        if (CollUtil.isNotEmpty(list)) {
            /**
             * 根据订单Id查询对应的订单信息
             */
            List<TransportOrderVO> transportOrderVOS = getOrderVOS(list);
            transportOrderDetailsVO.setOrderVOS(transportOrderVOS);


            /**
             * 因为是在同一种订单分类中,其对应的线路,车次,车辆,司机,订单分类信息都是一样的
             */

            /**
             * 获取车次车辆司机Id
             */
            OrderClassifyAttach classifyAttach = dispatchFeign.findOrderClassifyAttachByOrderId(list.get(0).getOrderId());

            /**
             * 获取订单分类数据
             */
            OrderClassify orderClassify = getOrderClassify(list);
            /**
             * 获取订单分类起始机构
             */
            if (StringUtils.isNotBlank(orderClassify.getStartAgencyId())) {
                CoreOrg startAgency = baseFeign.findCoreOrgById(orderClassify.getStartAgencyId()).getData();
                transportOrderDetailsVO.setStartCoreOrg(startAgency);
            }

            /**
             * 获取订单分类终点机构
             */
            if (StringUtils.isNotBlank(orderClassify.getEndAgencyId())) {
                CoreOrg endAgency = baseFeign.findCoreOrgById(orderClassify.getEndAgencyId()).getData();
                transportOrderDetailsVO.setEndCoreOrg(endAgency);
            }
            transportOrderDetailsVO.setOrderClassify(orderClassify);
            /**
             * 获取线路Id
             */
            String lineId = dispatchFeign.getLineByOrderClassifyId(list.get(0).getOrderClassifyId()).getData();
            if (StringUtils.isNotBlank(lineId)) {
                /**
                 * 获取该订单下的车次车辆司机信息
                 */
                TransportLineVO transportLineVO = getTransportLineVO(classifyAttach, lineId);
                transportOrderDetailsVO.setTransportLineVO(transportLineVO);
            }
            return new R<>(ResultCode.SUCCESS_CODE, transportOrderDetailsVO);
        }

        return new R<>(ResultCode.ERROR_CODE, transportOrderDetailsVO);
    }

    /**
     * 获取运单数量
     *
     * @return
     */
    @Override
    public R<TransportOrderDashboardVO> getTransportOrderCount() {
        TransportOrderDashboardVO t = new TransportOrderDashboardVO();

        /**
         * 运单总数
         */
        t.setTransportOrderTotal(count(null));
        QueryWrapper<TransportOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        /**
         * 待发车
         */
        t.setReadyToDepart(count(queryWrapper));

        /**
         * 运输中
         */
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 2);
        t.setInTransit(count(queryWrapper));

        /**
         * 到达
         */
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 3);
        t.setArrived(count(queryWrapper));
        return new R<>(ResultCode.SUCCESS_CODE, t);
    }

    /**
     * 获取线路数据
     *
     * @param classifyAttach
     * @param lineId
     * @return
     */
    private TransportLineVO getTransportLineVO(OrderClassifyAttach classifyAttach, String lineId) {
        /**
         * 获取该订单下的车次车辆司机信息
         */
        TransportLineVO transportLineVO = baseFeign.findTransportLineVOById(lineId, classifyAttach.getTruckId(), classifyAttach.getDriverId(), classifyAttach.getTripsId()).getData();
        if (ObjectUtils.isNotEmpty(transportLineVO)) {
            if (StringUtils.isNotBlank(transportLineVO.getStartAgencyId())) {
                CoreOrg startAgency = baseFeign.findCoreOrgById(transportLineVO.getStartAgencyId()).getData();
                if (ObjectUtils.isNotEmpty(startAgency))
                    transportLineVO.setStartAgency(startAgency);
            }

            if (StringUtils.isNotBlank(transportLineVO.getEndAgencyId())) {
                CoreOrg endAgency = baseFeign.findCoreOrgById(transportLineVO.getEndAgencyId()).getData();
                if (ObjectUtils.isNotEmpty(endAgency))
                    transportLineVO.setEndAgency(endAgency);
            }
        }
        return transportLineVO;
    }

    /**
     * 获取订单分类数据
     *
     * @param list
     * @return
     */
    private OrderClassify getOrderClassify(List<OrderClassifyOrder> list) {
        /**
         * 获取订单分类数据
         */
        OrderClassify orderClassify = dispatchFeign.geOrderClassifyById(list.get(0).getOrderClassifyId()).getData();
        return orderClassify;
    }

    /**
     * 根据订单Id查询对应的订单信息
     *
     * @param list
     * @return
     */
    private List<TransportOrderVO> getOrderVOS(List<OrderClassifyOrder> list) {
        List<TransportOrderVO> transportOrderVOS = list.stream().map(o -> {
            Order order = orderFeign.getOrderById(o.getOrderId());
            TransportOrderVO transportOrderVO = new TransportOrderVO();
            if (ObjectUtils.isNotEmpty(order)) {
                BeanUtils.copyProperties(order, transportOrderVO);
                /**
                 * 通过订单Id查询其运单Id
                 */
                QueryWrapper<TransportOrder> q = new QueryWrapper<>();
                q.eq("order_id", transportOrderVO.getId());
                TransportOrder one = baseMapper.selectOne(q);
                if (ObjectUtils.isNotEmpty(one)) {
                    transportOrderVO.setTransportOrderId(one.getId());
                }
            }
            return transportOrderVO;
        }).collect(Collectors.toList());
        return transportOrderVOS;
    }

    /**
     * 获取线路信息
     *
     * @param transportOrderDTO
     */
    private void getLineInformation(TransportOrderDTO transportOrderDTO) {

        CacheLineUse use = dispatchFeign.findCacheLineById(transportOrderDTO.getOrderId());
        if (ObjectUtils.isNotEmpty(use)) {
            if (StringUtils.isNotBlank(use.getCacheLineId())) {
                R<TransportLineDto> r = baseFeign.fineById(use.getCacheLineId());
                if (ObjectUtils.isNotEmpty(r.getData())) {
                    TransportLineDto transportLineDto = r.getData();
                    if (ObjectUtils.isNotEmpty(transportLineDto)) {
                        transportOrderDTO.setTransportLineDto(transportLineDto);
                    }
                }
            }


        }
    }

    /**
     * 获取车次车辆
     *
     * @param transportOrderDTO
     */
    private void getTheVehicleDriver(TransportOrderDTO transportOrderDTO) {
        OrderClassifyAttach classifyAttach = dispatchFeign.findOrderClassifyAttachByOrderId(transportOrderDTO.getOrderId());
        if (ObjectUtils.isNotEmpty(classifyAttach)) {
            /**
             * 获取所有车队
             */
            R<List<FleetDto>> r3 = baseFeign.findAll(null, null);
            if (ObjectUtils.isNotEmpty(r3.getData())) {
                List<FleetDto> list = r3.getData();
                if (StringUtils.isNotBlank(classifyAttach.getTruckId())) {
                    /**
                     * 获取车辆数据
                     */
                    R<TruckDto> r = baseFeign.findTruckById(classifyAttach.getTruckId());
                    if (ObjectUtils.isNotEmpty(r.getData())) {
                        TruckDto truckDto = r.getData();
                        if (ObjectUtils.isNotEmpty(truckDto)) {
                            if (CollUtil.isNotEmpty(list)) {
                                TruckDto dto = list.stream().filter(t -> t.getId().equals(truckDto.getFleetId())).map(t -> {
                                    truckDto.setFleetName(t.getName());
                                    return truckDto;
                                }).findFirst().get();
                                transportOrderDTO.setTruckDto(dto);
                            }
                        }
                    }
                }


                if (StringUtils.isNotBlank(classifyAttach.getDriverId())) {
                    /**
                     * 获取司机数据
                     */
                    R<TruckDriverDto> r1 = baseFeign.findOneDriver(classifyAttach.getDriverId());
                    if (ObjectUtils.isNotEmpty(r1.getData())) {
                        TruckDriverDto truckDriverDto = r1.getData();

                        if (ObjectUtils.isNotEmpty(truckDriverDto)) {
                            /**
                             * 获取所有用户进行过滤,找到指定用户
                             */
                            R<List<GlobalUser>> r4 = baseFeign.queryAll();
                            if (ObjectUtils.isEmpty(r4.getData())) {
                                throw new TmsException(ResultCode.ERROR_CODE, "对象为空!");
                            }
                            List<GlobalUser> list2 = r4.getData();
                            if (CollUtil.isNotEmpty(list2)) {
                                list2.stream().filter(u -> String.valueOf(u.getId()).equals(truckDriverDto.getUserId())).map(user -> {
                                    truckDriverDto.setName(user.getName());
                                    return truckDriverDto;
                                }).collect(Collectors.toList());
                            }

                            if (CollUtil.isNotEmpty(list)) {
                                /**
                                 * 获取所有车队,找到指定车队名称
                                 */
                                list.stream().filter(f -> f.getId().equals(truckDriverDto.getFleetId())).map(f -> {
                                    truckDriverDto.setFleetName(f.getName());
                                    return truckDriverDto;
                                }).collect(Collectors.toList());
                            }
                            transportOrderDTO.setTruckDriverDto(truckDriverDto);
                        }
                    }
                }

                if (StringUtils.isNotBlank(classifyAttach.getTripsId())) {
                    /**
                     * 获取车次数据
                     */
                    R<TransportTripsDto> r2 = baseFeign.fineTripsById(classifyAttach.getTripsId());
                    if (ObjectUtils.isNotEmpty(r2.getData())) {
                        TransportTripsDto transportTripsDto = r2.getData();
                        if (ObjectUtils.isNotEmpty(transportTripsDto)) {
                            transportOrderDTO.setTransportTripsDto(transportTripsDto);
                        }
                    }
                }
            }

        }
    }
}
